package com.vonchange.headb.core;

import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import com.vonchange.headb.core.bean.SqlParmeter;
import com.vonchange.headb.core.constant.HeaConstant;
import com.vonchange.headb.core.dialect.Dialect;
import com.vonchange.headb.core.map.HeaGetMap;
import com.vonchange.headb.core.map.HeaMap;
import com.vonchange.headb.core.page.IPage;
import com.vonchange.headb.utils.bean.HBeanUtils;
import com.vonchange.headb.utils.convert.HConvertUtils;
import com.vonchange.headb.utils.map.HMyHashMap;


/**
 *抽象的HeaDao：包含增删改查
 * @author von_change@163.com
 * @date 2015-6-14 下午6:36:40
 * @param <T>
 */
public abstract class AbstractHeaDao<T> extends HeaSoul<T> {
	@Resource
	protected Dialect dialect;
	protected void setDialect(Dialect dialect) {
		this.dialect = dialect;
	}
    /**
     *  插入SQL
     * @param sql
     * @param parameter
     * @return 主键
     */
    protected abstract Object insert(String sql, Object[] parameter);
	/**
	 * 删除SQL
	 * @param sql
	 * @param parameter
	 * @return 删除的列
	 */
	protected abstract int delete(String sql, Object[] parameter);
	/**
	 * 更新SQL
	 * @param sql
	 * @param parameter
	 * @return 更新的列
	 */
	protected abstract int update(String sql, Object[] parameter);
	/**
	 * 查询列表
	 * @param sql
	 * @param params
	 * @param aliasMap
	 * @return List
	 */
	protected abstract List<T> queryList(String sql, Object[] params, Map<String, String> aliasMap);

	/**
	 * 查询唯一的一行
	 * @param sql
	 * @param params
	 * @param aliasMap
	 * @return 一行
	 */
	protected abstract T queryOne(String sql, Object[] params, Map<String, String> aliasMap);

	/**
	 * 查询唯一
	 * @param sql
	 * @param params
	 * @param aliasMap
	 * @return HeaGetMap
	 */
	protected abstract HeaGetMap queryUnique(String sql, Object[] params, Map<String, String> aliasMap);
	/**
	 * 调用存储过程
	 * @param sql
	 * @param params
	 * @return HeaGetMap
	 */
	protected abstract HeaGetMap callProc(String sql, Object[] params);
	/**
	 * 调用存储过程
	 * @param sql
	 * @param params
	 * @return List<HeaGetMap>
	 */
	protected abstract List<HeaGetMap> callProcList(String sql, Object[] params);
	/**
	 * 计算sql的条数
	 * @param sql
	 * @param params
	 * @return 条数
	 */
	protected abstract long countMySqlResult(String sql, Object[] params);

	/**
	 * 保存
	 * @param entity
	 * @return 实体
	 */
	public final T  save(T entity) {
		SqlParmeter sqlParmeter = generateInsertSql(entity);
	    Object id=insert(sqlParmeter.getSql(), sqlParmeter.getParameters());
	    if(null!=id){
	    	HBeanUtils.setProperty(entity, sqlParmeter.getIdName(), id);
	    }
		return entity;
	}

	/**
	 * 查询列表
	 * @param parameter
	 * @return List<T>
	 */
	public final List<T> findList(HeaMap parameter) {
		if (null == parameter) {
			parameter = new HeaMap();
		}
		SqlParmeter sqlParmeter = generateQuerySql(parameter);
		String sql = sqlParmeter.getSql();
		Object[] params = sqlParmeter.getParameters();
		if (null != parameter.get(HeaConstant.Instruction.ADDENDNUM)) {
			int end = HConvertUtils.toInteger(parameter.get(HeaConstant.Instruction.ADDENDNUM));
			int begin = 0;
			Object beginObj = parameter.get(HeaConstant.Instruction.ADDBEGINNUM);
			if (null != beginObj) {
				begin = HConvertUtils.toInteger(beginObj);
			}
			sql = dialect.getPageSql(sql, begin, end-begin);
		}

		return queryList(sql, params, sqlParmeter.getAliasMap());
	}

	/**
	 * 查询第一条
	 * @param parameter
	 * @return T
	 */
	public final T findFirst(HeaMap parameter) {
		SqlParmeter sqlParmeter = generateQuerySql(parameter);
		String sql = sqlParmeter.getSql();
		Object[] params = sqlParmeter.getParameters();
		sql = dialect.getPageSql(sql, 0, 1);
		return queryOne(sql, params, sqlParmeter.getAliasMap());
	}

	/**
	 * 查询唯一一条
	 * @param parameter
	 * @return T
	 */
	public final T findOne(HeaMap parameter) {
		SqlParmeter sqlParmeter = generateQuerySql(parameter);
		String sql = sqlParmeter.getSql();
		Object[] params = sqlParmeter.getParameters();
		return queryOne(sql, params, sqlParmeter.getAliasMap());
	}

	/**
	 * 根据Id查询
	 * @param id
	 * @return T
	 */
	public final T findById(Object id) {
		SqlParmeter sqlParmeter = generateFindByIdSql(id);	
		String sql = sqlParmeter.getSql();
		Object[] params = sqlParmeter.getParameters();
		return queryOne(sql, params, sqlParmeter.getAliasMap());
	}

	/**
	 * 查询唯一一条
	 * @param parameter
	 * @return HeaGetMap
	 */
	public final HeaGetMap findUnique(HeaMap parameter) {
		if (null == parameter) {
			parameter = new HeaMap();
		}
		SqlParmeter sqlParmeter = generateQuerySql(parameter);
		String sql = sqlParmeter.getSql();
		Object[] params = sqlParmeter.getParameters();
		if (null != parameter.get(HeaConstant.Instruction.ADDENDNUM)) {
			int end = HConvertUtils.toInteger(parameter.get(HeaConstant.Instruction.ADDENDNUM));
			int begin = 0;
			Object beginObj = parameter.get(HeaConstant.Instruction.ADDBEGINNUM);
			if (null != beginObj) {
				begin = HConvertUtils.toInteger(beginObj);
			}
			sql = dialect.getPageSql(sql, begin, end-begin);
		}
		return queryUnique(sql, params, sqlParmeter.getAliasMap());
	}

	/**
	 * 分页查询
	 * @param page
	 * @param parameter
	 * @return IPage<T>
	 */
	public final IPage<T> findPage(IPage<T> page, HeaMap parameter) {
		SqlParmeter sqlParmeter = generateQuerySql(parameter);
		String sql = sqlParmeter.getSql();
		Object[] params = sqlParmeter.getParameters();
		long totalCount = countMySqlResult(sql, params);
		page.setEntityCount((int) totalCount);
		sql = dialect.getPageSql(sql, page.getFirstEntityIndex(), page.getPageSize());
		List<T> entities = queryList(sql, params, sqlParmeter.getAliasMap());
		page.setEntities(entities);
		return page;
	}
	public long count(HeaMap parameter){
		SqlParmeter sqlParmeter = generateQuerySql(parameter);
		String sql = sqlParmeter.getSql();
		Object[] params = sqlParmeter.getParameters();
		long totalCount = countMySqlResult(sql, params);
		return totalCount;
	}
	
	/**
	 * 删除
	 * @param parameter
	 * @return 删除的列
	 */
	public final  int delete(HeaMap parameter) {
		SqlParmeter sqlParmeter = generateDeleteSql(parameter);
		int result = delete(sqlParmeter.getSql(), sqlParmeter.getParameters());
		return result;
	}
	/**
	 *  根据Id删除
	 * @param id
	 * @return 0或1
	 */
	public final int deleteById(Object id) {
		SqlParmeter sqlParmeter = generateDeleteByIdSql(id);
		int result = delete(sqlParmeter.getSql(), sqlParmeter.getParameters());
		return result;
	}
	/**
	 * 根据实体删除
	 * @param entity
	 * @return 0或1
	 */
	public final int delete(T entity) {
		return deleteById(getId(entity));
	}
	/**
	 * 更新不为null的列
	 * @param entity
	 * @param parameter
	 * @return 更新的列
	 */
	public final int update(T entity,HeaMap parameter) {
		SqlParmeter sqlParmeter = generateUpdateSql(entity, parameter);
		int result = update(sqlParmeter.getSql(), sqlParmeter.getParameters());
		return result;
	}
	/**
	 * 根据Id更新（可设置更新为NULL值得字段）
	 * @param entity
	 * @param nullFields
	 * @return 0或1
	 */
	public int update(T entity,String... nullFields) {
		SqlParmeter sqlParmeter = generateUpdateEntitySql(entity,nullFields);
		int result = update(sqlParmeter.getSql(), sqlParmeter.getParameters());
		return result;
	}
	public final int updateNotB(T entity,HeaMap parameter) {
		SqlParmeter sqlParmeter = generateUpdateSql(entity, parameter);
		int result = update(sqlParmeter.getSql(), sqlParmeter.getParameters());
		return result;
	}
	/**
	 *  根据Id更新
	 * @param entity
	 * @return 0或1
	 */
	public final int update(T entity) {
		SqlParmeter sqlParmeter = generateUpdateEntitySql(entity);
		int result = update(sqlParmeter.getSql(), sqlParmeter.getParameters());
		return result;
	}
	/**
	 * 执行增删改语句
	 * @param cudSql
	 * @param parameter
	 * @return
	 */
	public final int cud(String cudSql,HMyHashMap parameter){
		SqlParmeter sqlParmeter = generateCudSqlFromXml(cudSql,parameter);
		int result = update(sqlParmeter.getSql(), sqlParmeter.getParameters());
		return result;
	}
	/**
	 * 调用存储过程
	 * @param procedureName 存储名
	 * @param parameter 
	 * @return HeaGetMap
	 */
	public final HeaGetMap callProcedure(String procedureName,Object... parameter){
		int paramNum=0;
		if(null!=parameter){
			paramNum=parameter.length;
		}
		String sql = generateProcedureSql(procedureName,paramNum);
		HeaGetMap map = callProc(sql,parameter);
		return map;
	}
	/**
	 * 调用存储过程
	 * @param procedureName
	 * @param parameter
	 * @return List<HeaGetMap>
	 */
	public final  List<HeaGetMap> callProcedureList(String procedureName,Object... parameter){
		int paramNum=0;
		if(null!=parameter){
			paramNum=parameter.length;
		}
		String sql = generateProcedureSql(procedureName,paramNum);
		List<HeaGetMap> mapList = callProcList(sql,parameter);
		return mapList;
	}

	

	

}
